﻿using System.Collections;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using DeepEarth.Core.Controls;

namespace DeepEarth.Toolkit.Common.Controls
{
    public class HeaderedTemplatedItemsControl : ItemsControl
    {
        public HeaderedTemplatedItemsControl()
        {
            DefaultStyleKey = typeof(HeaderedTemplatedItemsControl);
        }

        #region Properties
        public static readonly DependencyProperty HeaderMemberPathProperty = DependencyProperty.Register("HeaderMemberPath", typeof(string), typeof(HeaderedTemplatedItemsControl), null);
        public string HeaderMemberPath
        {
            get { return (string)GetValue(HeaderMemberPathProperty); }
            set { SetValue(HeaderMemberPathProperty, value); }
        }

        public static readonly DependencyProperty ChildItemsSourceProperty = DependencyProperty.Register("ChildItemsSource", typeof(string), typeof(HeaderedTemplatedItemsControl), null);
        public string ChildItemsSource
        {
            get { return (string)GetValue(ChildItemsSourceProperty); }
            set { SetValue(ChildItemsSourceProperty, value); }
        }

        public static readonly DependencyProperty ItemTemplateSelectorProperty = DependencyProperty.Register("ItemTemplateSelector", typeof(TemplateSelector), typeof(HeaderedTemplatedItemsControl), null);
        public TemplateSelector ItemTemplateSelector
        {
            get { return (TemplateSelector)GetValue(ItemTemplateSelectorProperty); }
            set { SetValue(ItemTemplateSelectorProperty, value); }
        }

        public static readonly DependencyProperty HeaderTemplateSelectorProperty = DependencyProperty.Register("HeaderTemplateSelector", typeof(TemplateSelector), typeof(HeaderedTemplatedItemsControl), null);
        public TemplateSelector HeaderTemplateSelector
        {
            get { return (TemplateSelector)GetValue(HeaderTemplateSelectorProperty); }
            set { SetValue(HeaderTemplateSelectorProperty, value); }
        }

        public static readonly DependencyProperty ItemSelectedCommandProperty = DependencyProperty.Register("ItemSelectedCommand", typeof(ICommand), typeof(HeaderedTemplatedItemsControl), null);
        public ICommand ItemSelectedCommand
        {
            get { return (ICommand)GetValue(ItemSelectedCommandProperty); }
            set { SetValue(ItemSelectedCommandProperty, value); }
        }

        public static readonly DependencyProperty HideItemsWhenEmptyProperty = DependencyProperty.Register("HideItemsWhenEmpty", typeof(bool), typeof(HeaderedTemplatedItemsControl), new PropertyMetadata(false));
        public bool HideItemsWhenEmpty
        {
            get { return (bool)GetValue(HideItemsWhenEmptyProperty); }
            set { SetValue(HideItemsWhenEmptyProperty, value); }
        }
        #endregion

        protected override DependencyObject GetContainerForItemOverride()
        {
            return new HeaderedTemplatedItem {HideWhenEmpty = HideItemsWhenEmpty};
        }

        protected override void PrepareContainerForItemOverride(DependencyObject element, object item)
        {
            base.PrepareContainerForItemOverride(element, item);

            var headeredItem = (HeaderedTemplatedItem)element;
            headeredItem.ItemTemplateSelector = ItemTemplateSelector;

            var itemType = item.GetType();
            if (string.IsNullOrWhiteSpace(HeaderMemberPath))
                headeredItem.Header = item;
            else
            {
                var headerPath = new PropertyPath(HeaderMemberPath);
                var hpi = itemType.GetProperty(headerPath.Path);
                headeredItem.Header = hpi.GetValue(item, null);
            }

            var headerTemplate = HeaderTemplateSelector.FindTemplate<DataTemplate>(headeredItem.Header);
            headeredItem.HeaderTemplate = headerTemplate;

            var childItemsPath = new PropertyPath(ChildItemsSource);
            var cpi = itemType.GetProperty(childItemsPath.Path);
            var childItems = cpi.GetValue(item, null) as IEnumerable;

            if (childItems != null)
                headeredItem.ItemsSource = childItems;

            headeredItem.ItemSelectedCommand = ItemSelectedCommand;
        }       
    }
}